#include <QFont>
#include <QHeaderView>
#include <QBoxLayout>

#include "indexview.h"

#include <dynamicviewsettings.h>

//////// Class 'IndexViewModel' implementation ////////////////////////////////////////////////////

IndexViewModel::IndexViewModel(ObjectsIndex * index, QObject * parent)
    : QAbstractTableModel(parent)
{
    m_index = index;
}

Qt::ItemFlags IndexViewModel::flags( const QModelIndex & index ) const
{
    return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
}

//////// Class 'IndexViewDataModel' implementation ////////////////////////////////////////////////////

IndexViewDataModel::IndexViewDataModel(ObjectsIndex *index, QObject *parent)
    : IndexViewModel(index)
{
    m_list = index->objects(ARSObject::Form | ARSObject::Field);
}

ARSDummyObject * IndexViewDataModel::objectForIndex( const QModelIndex & index ) const
{
    return m_list.at(index.row());
}

int IndexViewDataModel::rowCount( const QModelIndex & parent ) const
{
    Q_UNUSED(parent);
    return m_list.count();
}

int IndexViewDataModel::columnCount( const QModelIndex & parent ) const
{
    Q_UNUSED(parent);
    return 2;
}

QVariant IndexViewDataModel::data( const QModelIndex & index, int role ) const
{
    if(!index.isValid())
        return QVariant();

    if(index.row() < 0 || index.row() >= m_index->objects().count())
        return QVariant();

    if(role == Qt::DisplayRole || role == Qt::EditRole)
    {
        ARSDummyObject * object = objectForIndex(index);

        if(index.column() == 0)
            return object->name(true);

        if(index.column() == 1)
        {
            switch(object->type())
            {
            case ARSObject::Field:
                return tr("Field");
                break;

            case ARSObject::Form:
                return tr("Form");
                break;

            default:
                return QVariant();
            }
        }
    }

    if(role == Qt::UserRole)
        return QVariant::fromValue(m_index->objects().at(index.row()));

    if(role == Qt::FontRole)
        return g_Settings.tableViewsFont();

    return QVariant();
}

QVariant IndexViewDataModel::headerData( int section, Qt::Orientation orientation,
                                   int role ) const
{
    if(role == Qt::DisplayRole && orientation == Qt::Horizontal)
    {
        if(section == 0)
            return QString("Name");

        if(section == 1)
            return tr("Type");
    }

    return QVariant();
}

//////// Class 'IndexViewWorkflowModel' implementation ////////////////////////////////////////////////////

IndexViewWorkflowModel::IndexViewWorkflowModel(ObjectsIndex *index, QObject *parent)
    : IndexViewModel(index)
{
    m_list = index->objects(ARSObject::ActiveLink | ARSObject::Filter);
}

ARSDummyObject * IndexViewWorkflowModel::objectForIndex( const QModelIndex & index ) const
{
    return m_list.at(index.row());
}

int IndexViewDataModel::rowCount( const QModelIndex & parent ) const
{
    Q_UNUSED(parent);
    return m_list.count();
}

int IndexViewWorkflowModel::columnCount( const QModelIndex & parent ) const
{
    Q_UNUSED(parent);
    return 2;
}

QVariant IndexViewWorkflowModel::data( const QModelIndex & index, int role ) const
{
    if(!index.isValid())
        return QVariant();

    if(index.row() < 0 || index.row() >= m_index->objects().count())
        return QVariant();

    if(role == Qt::DisplayRole || role == Qt::EditRole)
    {
        ARSDummyObject * object = objectForIndex(index);

        if(index.column() == 0)
            return object->name(true);

        if(index.column() == 1)
        {
            switch(object->type())
            {
            case ARSObject::ActiveLink:
                return tr("Active Link");
                break;

            case ARSObject::Filter:
                return tr("Filter");
                break;

            default:
                return QVariant();
            }
        }
    }

    if(role == Qt::UserRole)
        return QVariant::fromValue(m_index->objects().at(index.row()));

    if(role == Qt::FontRole)
        return g_Settings.tableViewsFont();

    return QVariant();
}

QVariant IndexViewWorkflowModel::headerData( int section, Qt::Orientation orientation,
                                   int role ) const
{
    if(role == Qt::DisplayRole && orientation == Qt::Horizontal)
    {
        if(section == 0)
            return QString("Name");

        if(section == 1)
            return tr("Type");
    }

    return QVariant();
}

//////// Class 'IndexViewGuideModel' implementation ////////////////////////////////////////////////////

IndexViewGuideModel::IndexViewGuideModel(ObjectsIndex *index, QObject *parent)
    : IndexViewModel(index)
{
    m_list = index->objects(ARSObject::Guide);
}

ARSDummyObject * IndexViewGuideModel::objectForIndex( const QModelIndex & index ) const
{
    return m_list.at(index.row());
}

int IndexViewGuideModel::rowCount( const QModelIndex & parent ) const
{
    Q_UNUSED(parent);
    return m_list.count();
}

int IndexViewGuideModel::columnCount( const QModelIndex & parent ) const
{
    Q_UNUSED(parent);
    return 2;
}

QVariant IndexViewGuideModel::data( const QModelIndex & index, int role ) const
{
    if(!index.isValid())
        return QVariant();

    if(index.row() < 0 || index.row() >= m_index->objects().count())
        return QVariant();

    if(role == Qt::DisplayRole || role == Qt::EditRole)
    {
        ARSDummyObject * object = objectForIndex(index);

        if(index.column() == 0)
            return object->name();

        if(index.column() == 1)
        {
            ARSDummyGuide * guide = qobject_cast<ARSDummyGuide *>(object);
            if(!guide)
                return QVariant();

            if(guide->objectsType() == ARSExecWorkflowObject::ActiveLink)
                return tr("Active Link Guide");
            else
                return tr("Filter Guide");
        }
    }

    if(role == Qt::UserRole)
        return QVariant::fromValue(m_index->objects().at(index.row()));

    if(role == Qt::FontRole)
        return g_Settings.tableViewsFont();

    return QVariant();
}

QVariant IndexViewGuideModel::headerData( int section, Qt::Orientation orientation,
                                   int role ) const
{
    if(role == Qt::DisplayRole && orientation == Qt::Horizontal)
    {
        if(section == 0)
            return QString("Name");

        if(section == 1)
            return tr("Type");
    }

    return QVariant();
}

///////// Class 'ARSDummyObject' implementation ////////////////////////////////////////////////////

ObjectsListView::ObjectsListView( QWidget * parent, ViewType type )
    : QTableView(parent)
{
    m_index = 0;
    m_filterModel = 0;
    m_type = type;

    QFile styleFile(g_Settings_skin_dir + "/objectslist.qss");
    styleFile.open(QIODevice::ReadOnly);
    setStyleSheet(styleFile.readAll());
    connect(this, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(itemDoubleClicked(QModelIndex)));
}

void ObjectsListView::setIndex( ObjectsIndex * index )
{
    IndexViewModel * model;

    switch(m_type)
    {
    case Data:
        model = IndexViewDataModel(index, this);
        break;
    case Workflow:
        model = IndexViewWorkflowModel(index, this);
        break;
    case Guide:
        model = IndexViewGuideModel(index, this);
        break;
    };

    IndexViewModel * model = new IndexViewModel(index, this);
    m_index = index;
    m_filterModel = new QSortFilterProxyModel(this);
    m_filterModel->setSourceModel(model);
    m_filterModel->setFilterKeyColumn(0);
    m_filterModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
    setModel(m_filterModel);

    QHeaderView * hHeader = horizontalHeader();
    hHeader->setResizeMode(0, QHeaderView::Interactive);
    hHeader->setResizeMode(1, QHeaderView::Interactive);
    hHeader->setResizeMode(2, QHeaderView::Interactive);

    hHeader->resizeSection(0, 500);

    QFontMetrics fontMetrics(g_Settings.tableViewsFont());
    verticalHeader()->setDefaultSectionSize(fontMetrics.height() + 4);
    verticalHeader()->hide();
    setShowGrid(false);
    setSelectionMode(SingleSelection);
    setSelectionBehavior(SelectRows);
    setSortingEnabled(true);
}

void ObjectsListView::setFilterString( const QString & text )
{
    m_filterModel->setFilterFixedString(text);
}

void ObjectsListView::itemDoubleClicked( const QModelIndex & index )
{
    emit objectDoubleClicked(index.data(Qt::UserRole).value<ARSDummyObject *>());
}

///////// Class 'ARSDummyObject' implementation ////////////////////////////////////////////////////

ObjectsListTypeDelegate::ObjectsListTypeDelegate( QObject * parent )
    : QItemDelegate(parent)
{

}

void ObjectsListTypeDelegate::paint( QPainter * painter, const QStyleOptionViewItem & option,
                                     const QModelIndex & index ) const
{
    ARSObject::Types objectType = index.data(Qt::UserRole).value<ARSObject::Types>();
    QString text;

    switch(objectType)
    {
    case ARSObject::ActiveLink:
        text = tr("Active Link");
        break;

    case ARSObject::Filter:
        text = tr("Filter");
        break;
    }

    painter->drawText(option.rect, Qt::AlignLeft | Qt::AlignVCenter, text);
}

///////// Class 'IndexViewWidet' implementation ////////////////////////////////////////////////////

IndexViewWidet::IndexViewWidet(QWidget * parent)
    : DynamicViewWidget(parent)
{
    QHBoxLayout * mainLayout = new QHBoxLayout(this);
    mainLayout->setContentsMargins(0, 0, 0, 0);

    QTabWidget * m_tabWidget = new QTabWidget(this);

    ObjectsListView * view;
    view = new ObjectsListView(this);

    mainLayout->addWidget(m_tabWidget);

    setLayout(mainLayout);
}

QString IndexViewWidet::pluginName() const
{
    return "indexview";
}

void IndexViewWidet::connectToolBarItems(const ToolBarItemList & items)
{

}

void IndexViewWidet::disconnectToolBarItems(const ToolBarItemList & items)
{

}

void IndexViewWidet::adjustToolbar(const ToolBarItemList & itemsList) const
{

}

void IndexViewWidet::setModel(DynamicModel * model)
{
    m_view->setIndex(model->index());
}

///////// Class 'IndexViewPugin' implementation ////////////////////////////////////////////////////

IndexViewPlugin::IndexViewPlugin(QObject * parent)
    : QObject(parent)
{

}

QString IndexViewPlugin::name()const
{
    return "indexview";
}

QString IndexViewPlugin::description()const
{
    return tr("This plugin provides ARS log file objects index");
}

bool IndexViewPlugin::loadSettings()
{
    return true;
}

QString IndexViewPlugin::viewName()const
{
    return tr("Index");
}

ViewWidget::ViewType IndexViewPlugin::viewType() const
{
    return ViewWidget::DynamicModelView;
}

QIcon IndexViewPlugin::icon(bool active)const
{
    QPixmap pixmap(20, 20);
    pixmap.fill(QColor(200, 200, 255));
    return QIcon(pixmap);
}

ViewWidget * IndexViewPlugin::createView(QWidget * parent)const
{
    return new IndexViewWidet(parent);
}

ToolBarItemList IndexViewPlugin::toolBarItems(QObject * parent)const
{
    return ToolBarItemList();
}

SettingsWidget * IndexViewPlugin::settingsWidget(QWidget * parent)const
{
    return 0;
}

void IndexViewPlugin::appEvent(AppEvent * event)
{
}

////////////////////////////////////////////////////////////////////////////////////////////////////

Q_EXPORT_PLUGIN2(indexview, IndexViewPlugin)

////////////////////////////////////////////////////////////////////////////////////////////////////
